package com.project.controller;

import com.project.biz.CmsOrderBiz;
import com.project.biz.CmsRecoveryOrderBiz;
import com.project.common.enums.LockEnum;
import com.project.common.enums.TimingEnum;
import com.project.redis.RedisClient2;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

/**
 * @Description: 定时任务处理
 * 使用fixedDelay配置,它的间隔时间是根据上次的任务结束的时候开始计时的。
 * 比如一个方法上设置了fixedDelay=5*1000，那么当该方法某一次执行结束后，开始计算时间，当时间达到5秒，就开始再次执行该方法。
 * @Author: zhuchi
 * @CreateDate: 2020/8/22 15:49
 * @Version: 1.0
 */
@Slf4j
@Component
public class TimingTaskController {

    /**
     * Redis服务
     */
    @Autowired
    private RedisClient2 redisClient2;

    /**
     * 商品订单业务层接口类
     */
    @Autowired
    private CmsOrderBiz orderBiz;

    /**
     * 回收订单业务层接口类
     */
    @Autowired
    private CmsRecoveryOrderBiz recoveryOrderBiz;

    /**
     * 定时查询超过24小时待付款的商品订单,执行系统取消操作
     * （5秒执行一次）
     */
    @Scheduled(fixedDelay = 5*1000)
    public void timingToBePaidOrder(){
        //超时时间（30分钟）
        Long expires = System.currentTimeMillis() + Long.parseLong(TimingEnum.LOCK_EXPIRES.Value());
        String expiresStr = String.valueOf(expires);
        //加锁
        if (this.redisClient2.lock(TimingEnum.TIMING_TO_BE_PAID_ORDER.Value(), expiresStr)){
            try {
                log.info("定时查询超过24小时待付款的商品订单,执行系统取消操作开始");
                Long startTime = System.currentTimeMillis();

                int result = this.orderBiz.updateTimingToBePaidOrder();

                Long endTime = System.currentTimeMillis();
                log.info("定时查询超过24小时待付款的商品订单,执行系统取消操作结束,更新{}条数据,耗时:{}毫秒", result, (endTime - startTime));
            }catch (Exception e){
                log.info("定时查询超过24小时待付款的商品订单,执行系统取消操作时发生异常:{}", e);
            }finally {
                //解锁
                this.redisClient2.unlock(TimingEnum.TIMING_TO_BE_PAID_ORDER.Value(), expiresStr);
            }
        }else {
            log.info("定时查询超过24小时待付款的商品订单,执行系统取消操作,未获取到锁");
        }
    }

    /**
     * 定时获取已过可领取时间,还未被领取的订单,执行系统取消
     * （5秒执行一次）
     */
    @Scheduled(fixedDelay = 5*1000)
    public void timingUpdateObsoleteRecoveryOrder(){
        //超时时间（30分钟）
        Long expires = System.currentTimeMillis() + Long.parseLong(TimingEnum.LOCK_EXPIRES.Value());
        String expiresStr = String.valueOf(expires);
        //加锁
        if (this.redisClient2.lock(TimingEnum.TIMING_UPDATE_OBSOLETE_RECOVERY_ORDER.Value(), expiresStr)){
            try {
                log.info("定时获取已过可领取时间,还未被领取的订单,执行系统取消开始");
                Long startTime = System.currentTimeMillis();

                int result = this.recoveryOrderBiz.updateObsoleteRecoveryOrder();

                Long endTime = System.currentTimeMillis();
                log.info("定时获取已过可领取时间,还未被领取的订单,执行系统取消结束,更新{}条数据,耗时:{}毫秒", result, (endTime - startTime));
            }catch (Exception e){
                log.info("定时获取已过可领取时间,还未被领取的订单,执行系统取消操作时发生异常:{}", e);
            }finally {
                //解锁
                this.redisClient2.unlock(TimingEnum.TIMING_UPDATE_OBSOLETE_RECOVERY_ORDER.Value(), expiresStr);
            }
        }else {
            log.info("定时获取已过可领取时间,还未被领取的订单,执行系统取消,未获取到锁");
        }
    }

    /**
     * 定时查询已签收7天后还未确认收货的订单,进行系统自动确认收货操作
     * （一小时执行一次）
     */
    @Scheduled(fixedDelay = 60*60*1000)
    public void timingUpdateConfirmReceiptOrder(){
        //超时时间（30分钟）
        Long expires = System.currentTimeMillis() + Long.parseLong(TimingEnum.LOCK_EXPIRES.Value());
        String expiresStr = String.valueOf(expires);
        //加锁
        if (this.redisClient2.lock(TimingEnum.TIMING_UPDATE_CONFIRM_RECEIPT_ORDER.Value(), expiresStr)){
            try {
                log.info("定时查询已签收7天后还未确认收货的订单,进行系统自动确认收货操作开始");
                Long startTime = System.currentTimeMillis();

                int result = this.orderBiz.updateConfirmReceiptOrder();

                Long endTime = System.currentTimeMillis();
                log.info("定时查询已签收7天后还未确认收货的订单,进行系统自动确认收货操作结束,更新{}条数据,耗时:{}毫秒", result, (endTime - startTime));
            }catch (Exception e){
                log.info("定时查询已签收7天后还未确认收货的订单,进行系统自动确认收货操作时发生异常:{}", e);
            }finally {
                //解锁
                this.redisClient2.unlock(TimingEnum.TIMING_UPDATE_CONFIRM_RECEIPT_ORDER.Value(), expiresStr);
            }
        }else {
            log.info("定时查询已签收7天后还未确认收货的订单,进行系统自动确认收货操作,未获取到锁");
        }
    }

    /**
     * 定时查询确认收货多少天后未评价的商品订单,执行系统自动评价操作
     * （一小时执行一次）
     */
    @Scheduled(fixedDelay = 60*60*1000)
    public void timingToBeEvaluatedOrder(){
        //超时时间（30分钟）
        Long expires = System.currentTimeMillis() + Long.parseLong(TimingEnum.LOCK_EXPIRES.Value());
        String expiresStr = String.valueOf(expires);
        //加锁
        if (this.redisClient2.lock(TimingEnum.TIMING_TO_BE_EVALUATED_ORDER.Value(), expiresStr)){
            try {
                log.info("定时查询确认收货多少天后未评价的商品订单,执行系统自动评价操作开始");
                Long startTime = System.currentTimeMillis();

                int result = this.orderBiz.updateToBeEvaluatedOrder();

                Long endTime = System.currentTimeMillis();
                log.info("定时查询确认收货多少天后未评价的商品订单,执行系统自动评价操作结束,更新{}条数据,耗时:{}毫秒", result, (endTime - startTime));
            }catch (Exception e){
                log.info("定时查询确认收货多少天后未评价的商品订单,执行系统自动评价操作发生异常:{}", e);
            }finally {
                //解锁
                this.redisClient2.unlock(TimingEnum.TIMING_TO_BE_EVALUATED_ORDER.Value(), expiresStr);
            }
        }else {
            log.info("定时查询确认收货多少天后未评价的商品订单,执行系统自动评价操作操作,未获取到锁");
        }
    }

}
